package com.ls.rbac.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ls.rbac.config.Result;
import com.ls.rbac.entity.Role;
import com.ls.rbac.entity.vo.RolePermissionVo;
import com.ls.rbac.entity.vo.RoleVo;
import com.ls.rbac.service.IPermissionService;
import com.ls.rbac.service.IRoleService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author liusheng
 * @since 2025--06--28
 */
@RestController
@RequestMapping("/role")
@Tag(name = "角色管理模块", description = "角色相关接口")
public class RoleController {

    @Resource
    private IRoleService roleService;

    @Resource
    private IPermissionService permissionService;

    @Operation(summary = "查询角色--分页", description = "分页查询角色列表,支持角色名称和编码过滤")
    @GetMapping("/page")
    @PreAuthorize("hasAuthority('sys:role:list')")
    public Result<IPage<Role>> page(
            @Parameter(description = "当前页码") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页条数") @RequestParam(defaultValue = "10") Integer size,
            @Parameter(description = "角色名称") @RequestParam(required = false) String roleName,
            @Parameter(description = "角色编码") @RequestParam(required = false) String roleCode) {
        Page<Role> page = new Page<>(current, size);
        Role role = new Role().setRoleCode(roleCode).setRoleName(roleName);
        IPage<Role> rolePage = roleService.getRolePage(page, role);
        return Result.success(rolePage);
    }

    @Operation(summary = "查询所有角色", description = "获取所有未删除的角色")
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('sys:role:list')")
    public Result<List<Role>> list() {
        try {
            List<Role> roles = roleService.list();
            return Result.success(roles);
        } catch (Exception e) {
            return Result.fail("获取角色列表失败：" + e.getMessage());
        }
    }

    @Operation(summary = "查询角色信息", description = "根据ID获取角色详情")
    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('sys:role:list')")
    public Result<Role> getById(@Parameter(description = "角色ID") @PathVariable Integer id) {
        try {
            Role role = roleService.getById(id);
            if (role == null) {
                return Result.fail("角色不存在");
            }
            return Result.success(role);
        } catch (Exception e) {
            return Result.fail("获取角色详情失败：" + e.getMessage());
        }
    }

    @Operation(summary = "新增角色", description = "新增角色并分配权限")
    @PostMapping
    @PreAuthorize("hasAuthority('sys:role:add')")
    public Result<Boolean> add(@RequestBody RolePermissionVo rolePermissionVO) {
        try {
            RoleVo roleVo = rolePermissionVO.getRole();
            Role role = BeanUtil.copyProperties(roleVo, Role.class);
            boolean success = roleService.saveRoleWithPermissions(
                    role,
                    rolePermissionVO.getPermissionIds());
            return success ? Result.success(true, "角色添加成功") : Result.fail("角色添加失败");
        } catch (Exception e) {
            return Result.fail("角色添加失败：" + e.getMessage());
        }
    }

    @Operation(summary = "修改角色", description = "修改角色信息并更新权限")
    @PutMapping
    @PreAuthorize("hasAuthority('sys:role:edit')")
    public Result<Boolean> update(@RequestBody RolePermissionVo rolePermissionVO) {
        try {
            RoleVo roleVo = rolePermissionVO.getRole();
            if (roleVo.getId() == null) {
                return Result.fail("角色ID不能为空");
            }
            if (ObjectUtil.isEmpty(roleVo.getRoleName())) {
                roleVo.setRoleName(null);
            }
            if (ObjectUtil.isEmpty(roleVo.getRoleCode())) {
                roleVo.setRoleCode(null);
            }
            if (ObjectUtil.isEmpty(roleVo.getRemark())) {
                roleVo.setRemark(null);
            }
            if (ObjectUtil.isEmpty(roleVo.getCreateId())) {
                roleVo.setCreateId(null);
            }
            Role role = roleService.getById(roleVo.getId());
            if (role == null) {
                return Result.fail("角色不存在");
            }
            BeanUtil.copyProperties(roleVo, role, CopyOptions.create().ignoreNullValue());
            boolean success = roleService.updateRoleWithPermissions(
                    role,
                    rolePermissionVO.getPermissionIds());
            return success ? Result.success(true, "角色更新成功") : Result.fail("角色更新失败");
        } catch (Exception e) {
            return Result.fail("角色更新失败：" + e.getMessage());
        }
    }

    @Operation(summary = "删除角色", description = "根据ID删除角色")
    @DeleteMapping("/{id}")
    @PreAuthorize("hasAuthority('sys:role:delete')")
    public Result<Boolean> delete(@Parameter(description = "角色ID") @PathVariable Integer id) {
        try {
            boolean success = roleService.deleteRoleWithPermissionsAndUserRole(id);
            return success ? Result.success(true, "角色删除成功") : Result.fail("角色删除失败");
        } catch (Exception e) {
            return Result.fail("角色删除失败：" + e.getMessage());
        }
    }

    @Operation(summary = "获取角色对应权限", description = "获取角色已分配的权限ID列表")
    @GetMapping("/permissions/{roleId}")
    @PreAuthorize("hasAuthority('sys:role:list')")
    public Result<List<Integer>> getRolePermissions(@Parameter(description = "角色ID") @PathVariable Integer roleId) {
        try {
            List<Integer> permissionIds = permissionService.getPermissionIdsByRoleId(roleId);
            return Result.success(permissionIds);
        } catch (Exception e) {
            return Result.fail("获取角色权限失败：" + e.getMessage());
        }
    }

    @Operation(summary = "分配权限", description = "为角色分配权限")
    @PostMapping("/permissions/{roleId}")
    @PreAuthorize("hasAuthority('sys:role:edit')")
    public Result<Boolean> assignPermissions(
            @Parameter(description = "角色ID") @PathVariable Integer roleId,
            @RequestBody List<Integer> permissionIds) {
        try {
            boolean success = roleService.updateRoleWithPermissions(
                    roleService.getById(roleId),
                    permissionIds);
            return success ? Result.success(true, "权限分配成功") : Result.fail("权限分配失败");
        } catch (Exception e) {
            return Result.fail("权限分配失败：" + e.getMessage());
        }
    }


}
